package com.ruoyi.business.projectTosView.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.business.projectRecord.domain.ProjectRecord;
import com.ruoyi.business.projectRecord.service.ProjectRecordService;
import com.ruoyi.business.projectTosView.domain.VProjectTos;
import com.ruoyi.business.projectTosView.domain.params.VProjectTosQueryParams;
import com.ruoyi.business.projectTosView.mapper.VProjectTosMapper;
import com.ruoyi.business.projectTosView.service.VProjectTosService;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.contract.domain.ConBusiness;
import com.ruoyi.contract.service.IConBusinessService;
import com.ruoyi.finance.collection.service.BillCollectionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author 80661
 * @description 针对表【V_PROJECT_TOS】的数据库操作Service实现
 * @createDate 2023-07-04 09:12:51
 */
@Service
public class VProjectTosServiceImpl extends ServiceImpl<VProjectTosMapper, VProjectTos> implements VProjectTosService {

    @Autowired
    private VProjectTosMapper vProjectTosMapper;
    @Autowired
    private ProjectRecordService projectRecordService;
    @Autowired
    private IConBusinessService conBusinessService;


    /**
     * 获取VProjectTos By params
     *
     * @param params
     * @return
     */
    @Override
    public List<VProjectTos> listByParams(VProjectTosQueryParams params) {

        // 1.创建queryWrapper
        QueryWrapper<VProjectTos> queryWrapper = new QueryWrapper<>();


        // 2.构造查询条件

        // gkey 表ID(等同于BIZ_ID) eq查询
        queryWrapper.eq(params.getGkey() != null, "SHIP_VISIT_GKEY", params.getGkey());
        // companyCod 码头名称 eq查询
        queryWrapper.eq(StringUtils.isNotEmpty(params.getCompanyCod()),"COMPANY_COD", params.getCompanyCod());
        // PROJECT_TYPE 订单类型 in查询 参数里面是"projectTypeList": [ "disc_fee", "berth" ]
        queryWrapper.in(params.getProjectTypeList() != null && params.getProjectTypeList().size() > 0, "PROJECT_TYPE", params.getProjectTypeList());
        // reservationNo 预约号 like查询
        queryWrapper.like(StringUtils.isNotEmpty(params.getReservationNo()), "RESERVATION_NO", params.getReservationNo());
        // shipNam 船名 like查询
        queryWrapper.like(StringUtils.isNotEmpty(params.getShipNam()), "SHIP_NAM", params.getShipNam());
        // voyage 航次 like查询
        queryWrapper.eq(StringUtils.isNotEmpty(params.getVoyage()), "VOYAGE", params.getVoyage());
        // billNo 提单号 like查询
        queryWrapper.like(StringUtils.isNotEmpty(params.getBillNo()), "BILL_NO", params.getBillNo());
        // cargoName 货名 like查询
        queryWrapper.like(StringUtils.isNotEmpty(params.getCargoName()), "CARGO_NAME", params.getCargoName());
        // containerNo 集装箱号 like查询
        queryWrapper.like(StringUtils.isNotEmpty(params.getContainerNo()), "CONTAINER_NO", params.getContainerNo());
        // projectData 项目业务数据 like查询
        queryWrapper.like(StringUtils.isNotEmpty(params.getProjectData()), "PROJECT_DATA", params.getProjectData());
        // feeWay 结算方式 like查询
        queryWrapper.like(StringUtils.isNotEmpty(params.getFeeWay()), "FEE_WAY", params.getFeeWay());
        // customerCod 客户代码 like查询
        queryWrapper.like(StringUtils.isNotEmpty(params.getCustomerCod()), "CUSTOMER_COD", params.getCustomerCod());
        // customerNam 客户名称 like查询
        queryWrapper.like(StringUtils.isNotEmpty(params.getCustomerNam()), "CUSTOMER_NAM", params.getCustomerNam());
        // "dateRange": [ "2023-08-16", "2023-08-22" ]
        // private Date[] dateRange;
        // start_time 开始时间 ge查询
        // end_time 结束时间 le查询
        if (params.getDateRange() != null && params.getDateRange().length == 2) {
            queryWrapper.ge("START_TIME", params.getDateRange()[0]);
            Calendar calendar = new GregorianCalendar();
            calendar.setTime(params.getDateRange()[1]);
            calendar.add(Calendar.DATE, 1);
            Date endDate = calendar.getTime();
            queryWrapper.lt("END_TIME", endDate);
//            queryWrapper.le("END_TIME", params.getDateRange()[1]);
        }
        // ieType 进出口类型 eq查询
        queryWrapper.eq(StringUtils.isNotEmpty(params.getIeType()), "IE_TYPE", params.getIeType());
        // chargeStatus 收费状态 eq查询 (Long类型)
        queryWrapper.eq(params.getChargeStatus() != null, "CHARGE_STATUS", params.getChargeStatus());
        // feeWay 结算方式 eq查询
        queryWrapper.eq(params.getFeeWay() != null, "FEE_WAY", params.getFeeWay());

        // 3.执行查询
        List<VProjectTos> vProjectTosList = vProjectTosMapper.selectList(queryWrapper);

        // 4.返回结果
        return vProjectTosList;


    }


    /**
     * 固化tosProjectRecord、绑定合同（若合同不存在，则不固化）
     *
     * @param projectTosView
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ProjectRecord saveRecordAndBindContractForTosProjectView(VProjectTos projectTosView) {
        // 如果视图里面 已经有了projectId、conId，直接跳过，看下一条
        if (projectTosView.getProjectId() != null && projectTosView.getConId() != null) {
            return null;
        }
        // 查询最新版视图，（前端提交来的tosProjectView可能是几分钟前的老旧数据，没有projectId，但实际上最新视图里面是有projectId的）
        VProjectTos latestProjectTosView = this.getLatestProjectTosView(projectTosView);
        // 如果查不到视图，说明数据错乱，直接跳过
        if (latestProjectTosView == null) {
            return null;
        } else {
            // 如果最新版视图里面 已经有了projectId、conId，直接跳过，看下一条
            if (latestProjectTosView.getProjectId() != null && latestProjectTosView.getConId() != null) {
                return null;
            } else {
                // 根据最新版视图，get或者save对应的projectRecord
                ProjectRecord projectRecord = getOrCreateProjectRecord(latestProjectTosView);
                // 给projectRecord绑定合同，如果发生异常，则@Transactional回滚，不会固化projectRecord
                bindContractToProjectRecord(projectRecord);
                // 返回projectRecord，里面有projectId
                return projectRecord;
            }
        }

    }

    /**
     * 解绑合同 （根据conID删除projectTyp数据项 ）
     *
     * @param projectTosView
     * @return
     */
    public void unBindContract(VProjectTos projectTosView) {

        projectRecordService.removeById(projectTosView.getProjectId());

    }

    /**
     * 根据tosProjectView（因为可能是老旧数据），查询最新的tosProjectView（说不定已经带有了projectId）
     *
     * @param projectTosView
     * @return
     */
    private VProjectTos getLatestProjectTosView(VProjectTos projectTosView) {
        // 1.创建queryWrapper
        QueryWrapper<VProjectTos> queryWrapper = new QueryWrapper<>();

        // 2.构造查询条件
        queryWrapper.eq(projectTosView.getGkey() != null, "GKEY", projectTosView.getGkey())
                .eq(StringUtils.isNotEmpty(projectTosView.getCompanyCod()), "COMPANY_COD", projectTosView.getCompanyCod())
                .eq(StringUtils.isNotEmpty(projectTosView.getCfsCod()), "CFS_COD", projectTosView.getCfsCod())
                .eq(StringUtils.isNotEmpty(projectTosView.getProjectType()), "PROJECT_TYPE", projectTosView.getProjectType());


        // 3.执行查询
        return Optional.ofNullable(vProjectTosMapper.selectOne(queryWrapper))
                .orElse(null);
    }

    /**
     * 获取或创建ProjectRecord
     *
     * @param projectTosView
     * @return
     */
    private ProjectRecord getOrCreateProjectRecord(VProjectTos projectTosView) {
        // 如果视图有projectId，就getById，返回对应的projectRecord
        if (projectTosView.getProjectId() != null) {
            return projectRecordService.getById(projectTosView.getProjectId());
        } else {
            // 如果视图没有projectId，就save，返回对应的projectRecord
            // bean转换：projectTosView -> projectRecord
            ProjectRecord projectRecord = projectRecordService.convertProjectTosViewToProjectRecord(projectTosView);
            // 保存projectRecord
            projectRecordService.save(projectRecord);
            // 返回projectRecord，里面有projectId
            return projectRecord;
        }
    }


    /**
     * 给ProjectRecord绑定合同
     *
     * @param projectRecord
     */
    private void bindContractToProjectRecord(ProjectRecord projectRecord) {
        // 如果没有绑定合同，就绑定一个
        if (projectRecord.getConId() == null) {
            // 根据projectId查询合同
            List<ConBusiness> contracts = conBusinessService.listContractByProjectId(projectRecord.getProjectId());
            // 根据合同数量，绑定合同
            if (contracts.isEmpty()) {
                // 如果没有合同，爆出异常，回滚
                throw new RuntimeException(projectRecord.getGkey() + "没有合同");
            } else if (contracts.size() == 1) {
                // 如果只有一个合同，就绑定这个合同
                projectRecord.setConId(contracts.get(0).getConId());
                projectRecordService.updateById(projectRecord);
            } else {
                // 如果有多个合同，就抛出异常，回滚
                throw new RuntimeException(projectRecord.getGkey() + "有多个合同");
            }
        } else {
            // 如果已经绑定了合同，就不绑定了
        }
    }

}
			




